package com.guoguo.job;

import com.guoguo.base.StaticResource;
import com.guoguo.service.*;
import com.guoguo.utils.RedisUtils;
import com.guoguo.utils.SpringUtil;
import org.apache.commons.collections.map.HashedMap;
import org.apache.commons.dbcp.BasicDataSource;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;

import javax.annotation.Resource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.*;

/**
 * Created by Administrator on 2017/9/12 0012.
 */

     /*
                           _ooOoo_
                          o8888888o
                          88" . "88
                          (| -_- |)
                          O\  =  /O
                       ____/`---'\____
                     .'  \\|     |//  `.
                    /  \\|||  :  |||//  \
                   /  _||||| -:- |||||-  \
                   |   | \\\  -  /// |   |
                   | \_|  ''\---/''  |   |
                   \  .-\__  `-`  ___/-. /
                 ___`. .'  /--.--\  `. . __
              ."" '<  `.___\_<|>_/___.'  >'"".
             | | :  `- \`.;`\ _ /`;.`/ - ` : | |
             \  \ `-.   \_ __\ /__ _/   .-` /  /
        ======`-.____`-.___\_____/___.-`____.-'======
                           `=---='
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                 佛祖保佑       永无BUG
        */
public class  UpdateDateJob implements Job {

    private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(UpdateDateJob.class);
    private BasicDataSource dataSource;

    private RedisUtils redisUtils;

    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        logger.info("================>>>>>>>    定时任务 " + UpdateDateJob.class + "开始........");
        if (redisUtils == null) {
            redisUtils = RedisUtils.getInstance();
        }
        Set<String> upKeys = redisUtils.keys(StaticResource.SYS_INIT_UP + "*");
        Set<String> likeImageKeys = redisUtils.keys(StaticResource.SYS_INIT_IMAGE_LIKE + "*");//图片收藏key
        Set<String> likeAlbumKeys = redisUtils.keys(StaticResource.SYS_INIT_ALBUM_LIKE + "*");//专辑收藏key
        Set<String> shareImageKeys = redisUtils.keys(StaticResource.SYS_INIT_IMAGE_SHARE + "*");//图片分享key
        Set<String> shareAlbumKeys = redisUtils.keys(StaticResource.SYS_INIT_ALBUM_SHARE + "*");//专辑分享key
        Set<String> attentionKeys = redisUtils.keys(StaticResource.SYS_INIT_ATTENTION + "*");//关注key
        Set<String> sendImageCommentKeys = redisUtils.keys(StaticResource.SYS_INIT_IMAGE_COMMENT + "*");//对图片评论key
        Set<String> sendAlbumCommentKeys = redisUtils.keys(StaticResource.SYS_INIT_ALBUM_COMMENT + "*");//对专辑评论key

        //点赞
        commentUP(upKeys);
        //图片收藏和分享
        imageIike(likeImageKeys, shareImageKeys);
        //专辑收藏和分享
        albumIike(likeAlbumKeys, shareAlbumKeys);
        //关注模特
        attention(attentionKeys);
        //图片的关注
        sendImageComment(sendImageCommentKeys);
        //对专辑的评论
        sendAlbumComment(sendAlbumCommentKeys);

        logger.info("================>>>>>>>    定时任务 " + UpdateDateJob.class + "结束！");
    }

    /**
     * 点赞
     *
     * @param upKeys
     */
    private void commentUP(Set<String> upKeys) {
        logger.info("================>>>>>>>    更新评论点赞数开始......");
        StringBuffer sqlSb = new StringBuffer("UPDATE comment SET args_2 = args_2 + ? WHERE comm_id = ?");
        Connection connection = getConnection();
        PreparedStatement preparsStatement = null;
        try {

            preparsStatement = connection.prepareStatement(sqlSb.toString());
            connection.setAutoCommit(false);
            if (upKeys.size() > 0) {
                Iterator<String> iterator = upKeys.iterator();
                while (iterator.hasNext()) {
                    String upKey = iterator.next();
                    preparsStatement.setInt(1, Integer.valueOf(redisUtils.getset(upKey, "0")));
                    String[] keyArr = upKey.split(":");
                    preparsStatement.setString(2, keyArr[keyArr.length - 1]);
                    preparsStatement.addBatch();
                }
            }
            preparsStatement.executeBatch();
            logger.info("================>>>>>>>>   sql 执行成功，数据已经更新......");
            connection.commit();
            connection.setAutoCommit(true);
        } catch (SQLException e) {
            e.printStackTrace();
            try {
                if (!connection.isClosed()) {
                    connection.rollback();//4,当异常发生执行catch中SQLException时，记得要rollback(回滚)；
                    logger.info("================>>>>>>>>   sql 执行失败，进行回滚......");
                    connection.setAutoCommit(true);
                }
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
        } finally {
            try {
                preparsStatement.close();
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        logger.info("================>>>>>>>    更新评论点赞数结束！");
    }

    /**
     * 图片收藏和分享
     *
     * @param likeImageKeys
     * @param shareImageKeys
     */
    private void imageIike(Set<String> likeImageKeys,Set<String> shareImageKeys) {
        logger.info("================>>>>>>>    更新图片收藏开始......");
        StringBuffer sqlSb = new StringBuffer("UPDATE images SET favorite_num = favorite_num + ? ,share_num = share_num + ?  WHERE img_id = ?");
        Connection connection = getConnection();
        PreparedStatement preparsStatement = null;
        try {
            preparsStatement = connection.prepareStatement(sqlSb.toString());
            connection.setAutoCommit(false);

            Map<String, Map<String, String>> result = handleData(likeImageKeys, shareImageKeys);
            Set<String> keys = result.keySet();
            for (String key : keys) {
                Map<String, String> data = result.get(key);
                Set<String> dataKeys = data.keySet();
                int favorite_num = 0;
                int share_num = 0;
                for (String dataKey : dataKeys) {
                    String[] dataKeyArr = dataKey.split("_");
                    if ("like".equals(dataKeyArr[0])) {
                        favorite_num = Integer.valueOf(data.get(dataKey));
                    }
                    if ("share".equals(dataKeyArr[0])) {
                        share_num = Integer.valueOf(data.get(dataKey));
                    }
                }
                preparsStatement.setInt(1, favorite_num);
                preparsStatement.setInt(2, share_num);
                preparsStatement.setString(3, key);
                preparsStatement.addBatch();
            }
            preparsStatement.executeBatch();
            logger.info("================>>>>>>>>   sql 执行成功，数据已经更新......");
            connection.commit();
            connection.setAutoCommit(true);
        } catch (SQLException e) {
            e.printStackTrace();
            try {
                if (!connection.isClosed()) {
                    connection.rollback();//4,当异常发生执行catch中SQLException时，记得要rollback(回滚)；
                    logger.info("================>>>>>>>>   sql 执行失败，进行回滚......");
                    connection.setAutoCommit(true);
                }
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
        } finally {
            try {
                preparsStatement.close();
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        logger.info("================>>>>>>>    更新图片收藏结束！");
    }

    /**
     * 专辑收藏和分享
     *
     * @param likeAlbumKeys
     */
    private void albumIike(Set<String> likeAlbumKeys, Set<String> shareAlbumKeys) {
        logger.info("================>>>>>>>    更新专辑收藏开始......");
        StringBuffer sqlSb = new StringBuffer("UPDATE album SET favorite_num = favorite_num + ? ,share_num = share_num + ? WHERE alb_id = ?");
        Connection connection = getConnection();
        PreparedStatement preparsStatement = null;
        try {
            preparsStatement = connection.prepareStatement(sqlSb.toString());
            connection.setAutoCommit(false);

            Map<String, Map<String, String>> result = handleData(likeAlbumKeys, shareAlbumKeys);
            Set<String> keys = result.keySet();
            for (String key : keys) {
                Map<String, String> data = result.get(key);
                Set<String> dataKeys = data.keySet();
                int favorite_num = 0;
                int share_num = 0;
                for (String dataKey : dataKeys) {
                    String[] dataKeyArr = dataKey.split("_");
                    if ("like".equals(dataKeyArr[0])) {
                        favorite_num = Integer.valueOf(data.get(dataKey));
                    }
                    if ("share".equals(dataKeyArr[0])) {
                        share_num = Integer.valueOf(data.get(dataKey));
                    }
                }
                preparsStatement.setInt(1, favorite_num);
                preparsStatement.setInt(2, share_num);
                preparsStatement.setString(3, key);
                preparsStatement.addBatch();
            }
            preparsStatement.executeBatch();
            logger.info("================>>>>>>>>   sql 执行成功，数据已经更新......");
            connection.commit();
            connection.setAutoCommit(true);
        } catch (SQLException e) {
            e.printStackTrace();
            try {
                if (!connection.isClosed()) {
                    connection.rollback();//4,当异常发生执行catch中SQLException时，记得要rollback(回滚)；
                    logger.info("================>>>>>>>>   sql 执行失败，进行回滚......");
                    connection.setAutoCommit(true);
                }
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
        } finally {
            try {
                preparsStatement.close();
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        logger.info("================>>>>>>>    更新专辑收藏结束！");
    }

    /**
     * 关注
     *
     * @param attentionKeys
     */
    private void attention(Set<String> attentionKeys) {
        logger.info("================>>>>>>>    更新关注数开始......");
        StringBuffer sqlSb = new StringBuffer("UPDATE model SET fans_num = fans_num + ? WHERE model_id = ?");
        Connection connection = getConnection();
        PreparedStatement preparsStatement = null;
        try {
            preparsStatement = connection.prepareStatement(sqlSb.toString());
            connection.setAutoCommit(false);
            if (attentionKeys.size() > 0) {
                Iterator<String> iterator = attentionKeys.iterator();
                while (iterator.hasNext()) {
                    String upKey = iterator.next();
                    preparsStatement.setInt(1, Integer.valueOf(redisUtils.getset(upKey, "0")));
                    String[] keyArr = upKey.split(":");
                    preparsStatement.setString(2, keyArr[keyArr.length - 1]);
                    preparsStatement.addBatch();
                }
            }
            preparsStatement.executeBatch();
            logger.info("================>>>>>>>>   sql 执行成功，数据已经更新......");
            connection.commit();
            connection.setAutoCommit(true);
        } catch (SQLException e) {
            e.printStackTrace();
            try {
                if (!connection.isClosed()) {
                    connection.rollback();//4,当异常发生执行catch中SQLException时，记得要rollback(回滚)；
                    logger.info("================>>>>>>>>   sql 执行失败，进行回滚......");
                    connection.setAutoCommit(true);
                }
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
        } finally {
            try {
                preparsStatement.close();
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        logger.info("================>>>>>>>    更新关注数结束！");
    }

    /**
     * 批量处理缓存中的数据
     *
     * @param keyList
     * @return
     */
    private Map<String, Map<String, String>> handleData(Set<String>... keyList) {
        Map<String, Map<String, String>> result = new HashedMap();
        for (Set<String> keys : keyList) {
            Map<String, String> data = null;
            String keyName = new String();
            for (String key : keys) {
                String[] keyArr = key.split(":");
                keyName = keyArr[keyArr.length - 1];
                if (result.containsKey(keyName)) {
                    data = result.get(keyName);
                } else {
                    data = new HashedMap();
                }

                data.put(keyArr[keyArr.length - 2], redisUtils.getset(key, "0"));
                result.put(keyName, data);
            }
//            if (data != null) {
//
//            }
        }
        return result;
    }


    /**
     *对图片评论
     * @param sendImageCommentKeys
     */
    private void sendImageComment(Set<String> sendImageCommentKeys) {
        logger.info("================>>>>>>>    更新图片评论开始......");
        StringBuffer sqlSb = new StringBuffer("UPDATE images SET comment_num = comment_num + ? WHERE img_id = ?");
        Connection connection = getConnection();
        PreparedStatement preparsStatement = null;
        try {

            preparsStatement = connection.prepareStatement(sqlSb.toString());
            connection.setAutoCommit(false);
            if (sendImageCommentKeys.size() > 0) {
                Iterator<String> iterator = sendImageCommentKeys.iterator();
                while (iterator.hasNext()) {
                    String upKey = iterator.next();
                    preparsStatement.setInt(1, Integer.valueOf(redisUtils.getset(upKey, "0")));
                    String[] keyArr = upKey.split(":");
                    preparsStatement.setString(2, keyArr[keyArr.length - 1]);
                    preparsStatement.addBatch();
                }
            }
            preparsStatement.executeBatch();
            logger.info("================>>>>>>>>   sql 执行成功，数据已经更新......");
            connection.commit();
            connection.setAutoCommit(true);
        } catch (SQLException e) {
            e.printStackTrace();
            try {
                if (!connection.isClosed()) {
                    connection.rollback();//4,当异常发生执行catch中SQLException时，记得要rollback(回滚)；
                    logger.info("================>>>>>>>>   sql 执行失败，进行回滚......");
                    connection.setAutoCommit(true);
                }
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
        } finally {
            try {
                preparsStatement.close();
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        logger.info("================>>>>>>>    更新图片评论结束！");
    }

    /**
     * 专辑评论
     *
     * @param sendAlbumCommentKeys
     */
    private void sendAlbumComment(Set<String> sendAlbumCommentKeys) {
        logger.info("================>>>>>>>    更新专辑评论开始......");
        StringBuffer sqlSb = new StringBuffer("UPDATE album SET comment_num = comment_num + ? WHERE alb_id = ?");
        Connection connection = getConnection();
        PreparedStatement preparsStatement = null;
        try {

            preparsStatement = connection.prepareStatement(sqlSb.toString());
            connection.setAutoCommit(false);
            if (sendAlbumCommentKeys.size() > 0) {
                Iterator<String> iterator = sendAlbumCommentKeys.iterator();
                while (iterator.hasNext()) {
                    String upKey = iterator.next();
                    preparsStatement.setInt(1, Integer.valueOf(redisUtils.getset(upKey, "0")));
                    String[] keyArr = upKey.split(":");
                    preparsStatement.setString(2, keyArr[keyArr.length - 1]);
                    preparsStatement.addBatch();
                }
            }
            preparsStatement.executeBatch();
            logger.info("================>>>>>>>>   sql 执行成功，数据已经更新......");
            connection.commit();
            connection.setAutoCommit(true);
        } catch (SQLException e) {
            e.printStackTrace();
            try {
                if (!connection.isClosed()) {
                    connection.rollback();//4,当异常发生执行catch中SQLException时，记得要rollback(回滚)；
                    logger.info("================>>>>>>>>   sql 执行失败，进行回滚......");
                    connection.setAutoCommit(true);
                }
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
        } finally {
            try {
                preparsStatement.close();
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        logger.info("================>>>>>>>    更新专辑评论结束！");
    }


    /**
     * 获得connection
     *
     * @return
     */
    private Connection getConnection() {
        if (dataSource == null) {
            dataSource = (BasicDataSource) SpringUtil.getBean("dataSource");
        }
        try {
            return dataSource.getConnection();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }
}
